package com.mt.mtyx.common.utils.generate.generate.config;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.*;
import java.util.function.Supplier;

/**
 * @author WMT
 * @Date 2023/5/26 17:27
 */
public class DatabaseCodeConfig {

    /**
     * 类型隐射
     */
    private static final Map<String, Class<?>> FIELD_MAPPING = new HashMap<>();

    static {
        initTypeMap();
    }

    private static void initTypeMap() {
        FIELD_MAPPING.put("varchar", String.class);
        FIELD_MAPPING.put("text", String.class);
        FIELD_MAPPING.put("char", String.class);
        FIELD_MAPPING.put("decimal", BigDecimal.class);
        FIELD_MAPPING.put("int", int.class);
        FIELD_MAPPING.put("tinyint", byte.class);
        FIELD_MAPPING.put("smallint", short.class);
        FIELD_MAPPING.put("bigint", long.class);
        FIELD_MAPPING.put("time ", LocalTime.class);
        FIELD_MAPPING.put("date", LocalDate.class);
        FIELD_MAPPING.put("datetime", LocalDateTime.class);
    }

    public static Map<String, Class<?>> getTypeMap() {
        return FIELD_MAPPING;
    }

    /**
     * 添加类型隐射关系
     */
    public DatabaseCodeConfig addTypeMap(Map<String, Class<?>> map) {
        FIELD_MAPPING.putAll(map);
        return this;
    }

    /**
     * 用户名
     */
    private final String username;

    /**
     * 密码
     */
    private final String password;

    /**
     * 数据库连接url
     */
    private final String url;

    /**
     * 数据库连接驱动
     */
    private final String driver;


    public DatabaseCodeConfig(String username, String password, String url, String driver) {
        this.username = username;
        this.password = password;
        this.url = url;
        this.driver = driver;
    }

    /**
     * 字段前缀字符单词
     */
    private String fieldPrefixAlphabet;

    /**
     * 表格前缀
     */
    private String prefixTable;

    /**
     * 表格后缀
     */
    private String suffixTable;

    /**
     * 排除的表格
     */
    private Set<String> excludeTable;

    /**
     * 包含表格
     */
    private Set<String> includeTable;

    public String getUsername() {
        return username;
    }

    public String getPassword() {
        return password;
    }

    public String getUrl() {
        return url;
    }

    public String getDriver() {
        return driver;
    }

    public String getPrefixTable() {
        return prefixTable;
    }

    public String getSuffixTable() {
        return suffixTable;
    }

    public Set<String> getExcludeTable() {
        return excludeTable;
    }

    public Set<String> getIncludeTable() {
        return includeTable;
    }

    public DatabaseCodeConfig addPrefixTable(String prefixTable) {
        this.prefixTable = prefixTable;
        return this;
    }

    public DatabaseCodeConfig addPrefixTable(Supplier<String> supplier) {
        if (supplier != null) this.prefixTable = supplier.get();
        return this;
    }

    public DatabaseCodeConfig addSuffixTable(String suffix) {
        this.suffixTable = suffix;
        return this;
    }

    public DatabaseCodeConfig addSuffixTable(Supplier<String> supplier) {
        if (supplier != null) this.suffixTable = supplier.get();
        return this;
    }

    public DatabaseCodeConfig addExcludeTable(String... excludeTable) {
        this.excludeTable = new HashSet<>(Arrays.asList(excludeTable));
        return this;
    }

    public DatabaseCodeConfig addExcludeTable(Supplier<Set<String>> supplier) {
        if (supplier != null) this.excludeTable = supplier.get();
        return this;
    }

    public DatabaseCodeConfig addIncludeTable(String... includeTable) {
        this.includeTable = new HashSet<>(Arrays.asList(includeTable));
        return this;
    }

    public DatabaseCodeConfig addIncludeTable(Supplier<Set<String>> supplier) {
        if (supplier != null) this.includeTable = supplier.get();
        return this;
    }

    public String getFieldPrefixAlphabet() {
        return fieldPrefixAlphabet;
    }

    public DatabaseCodeConfig setFieldSuffixAlphabet(String fieldPrefixAlphabet) {
        this.fieldPrefixAlphabet = fieldPrefixAlphabet;
        return this;
    }
}
